﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.IO;
using System.Windows.Forms;

namespace NativeBayes
{
    public class Classifier
    {
        public Dictionary<string, long[]> fc = new Dictionary<string, long[]>() ;
        public long[] cc  = new long[2];
        //public DB db;
       
        public Classifier()
        {
            //fc = db.Loadfc();
            //cc = db.Loadcc();
            //this.db = db;
            string line1;

            //读取cc
            System.IO.StreamReader file1 = new System.IO.StreamReader("cc.txt");
            while ((line1 = file1.ReadLine()) != null)
            {
                string[] words = line1.Split(' ');
                cc[0] = Convert.ToInt64(words[0]);
                cc[1] = Convert.ToInt64(words[1]);
            }
           
            file1.Close();

            //读取fc
            string line;
            
            System.IO.StreamReader file2 =new System.IO.StreamReader("db.txt");
            while ((line = file2.ReadLine()) != null)
            {
                string[] words = line.Split(' ');
                long[] cat = new long[2];                       //Dictionary存储的只是一个索引
                cat[0] = Convert.ToInt64(words[1]);
              
                cat[1] = Convert.ToInt64(words[2]);
               // MessageBox.Show("like: " + cat[0].ToString() + "  dislike: " + cat[1].ToString());
                fc.Add(words[0], cat); 
            }
            
            file2.Close();


        }
        
        //为单词word的cat分类（like or dilike)计数
        
        public void incf(string word , int cat)
        {
            if (fc.ContainsKey(word))
            {
                //MessageBox.Show(fc[word][cat].ToString());
                fc[word][cat]++;
            }
            else
            {
                fc.Add(word, new long[3]);
                fc[word][0] = 0;
                fc[word][1] = 0;
                fc[word][2] = 1;                 //标记为新增词
                fc[word][cat] += 1;
                
               // db.db_incf(word, cat, 1);
            }
        
        }

        //增加cat分类（like or dilike)的总个数
        public void incc(int cat)
        {
            cc[cat]++;
        }

        //某个单词出现在某个分类中的次数
        public float fcount(string word, int cat)
        {
            if (fc.ContainsKey(word))
            {
                return (float)fc[word][cat];
            }
            return 0;
        }

        //某个分类出现的总次数
        public long catcount(int cat)
        {
            return cc[cat];
        }

        //返回总个数
        public long totalcount()
        {
            return (cc[0] + cc[1]);
        }

        //训练分类器
        public void train(List<string> word, int cat)
        {
            foreach (string w in word)
            {
                incf(w, cat);           //为单词word的cat分类（like or dilike)计数
            }
            incc(cat);                     //增加cat分类（like or dilike)的总个数
        }

        //某个单词在某个分类中出现的概率
        public double fprob(string word , int cat)
        {
            if (catcount(cat) == 0)
                return 0.0;
            return fcount(word, cat) / catcount(cat);
        }
        //某个单词出现在某个分类中的加权概率
        public double weightedprob(string word , int cat , double weight , double ap)
        {
            double basicprob = fprob(word, cat);
            double totals = fcount(word , 0) + fcount(word ,1);
            return ((weight * ap) + (totals * basicprob)) / (weight + totals);
        }

        //一段文本属于某个分类的概率
        public double docprob(List<string> word, int cat)
        {
            double p = 1;
            foreach (string w in word)
            {
                p *= weightedprob(w, cat, 1, 0.5);
            }
            return p;
        }

        //贝叶斯公式
        public double prob(List<string> word, int cat)
        {
            double catprob = catcount(cat) / totalcount();
            double docsprob = docprob(word, cat);
            return docsprob * catprob;
        }

        //增加cat分类（like or dilike)的总个数
        public void SaveData()
        {           
            //db.Updatecc(cc);
           // db.Updatefc(fc);
           
            //写入fc
            FileStream fst = new FileStream("db.txt", FileMode.OpenOrCreate);
            StreamWriter stw = new StreamWriter(fst, System.Text.Encoding.GetEncoding("utf-8"));//指定编码.否则将出错!

            foreach (var item in fc)
            {
                //MessageBox.Show("like: " + item.Value[0] + "  dislike: " + item.Value[0]);
                stw.WriteLine(item.Key + " " + item.Value[0] + " " + item.Value[1]);
            }
            stw.Close();
            fst.Close();

            //写入cc
            FileStream fst2 = new FileStream("cc.txt", FileMode.OpenOrCreate);//追加模式
            StreamWriter stw2 = new StreamWriter(fst2, System.Text.Encoding.GetEncoding("utf-8"));//指定编码.否则将出错!
            stw2.WriteLine(cc[0].ToString() + " " + cc[1].ToString());
            stw2.Close();
            fst2.Close();
        }
    }
}
